package com.internetCafes.spms.web.tenant.bizservice.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.internetCafes.spms.common.CommonConstants;
import com.internetCafes.spms.common.utils.DateUtils;
import com.internetCafes.spms.common.utils.StringUtils;
import com.internetCafes.spms.common.utils.entity.page.PageItemDTO;
import com.internetCafes.spms.common.utils.entity.page.PageItemUtil;
import com.internetCafes.spms.common.utils.entity.page.PageItemVO;
import com.internetCafes.spms.web.sys.model.ConfInfo;
import com.internetCafes.spms.web.sys.service.ConfInfoService;
import com.internetCafes.spms.web.tenant.bizservice.ITenantInfoPlusBizService;
import com.internetCafes.spms.web.tenant.dao.TenantInfoPlusMapper;
import com.internetCafes.spms.web.tenant.model.TenantInfoPlus;
import com.internetCafes.spms.web.tenant.model.podo.TenantCertificateCount;
import com.internetCafes.spms.web.tenant.model.podo.TenantInfoPlusDo;
import com.internetCafes.spms.web.tenant.model.podo.TenantInfoPlusPo;
import com.internetCafes.spms.web.tenant.model.req.TenantCountPagingReq;
import com.internetCafes.spms.web.tenant.model.res.TenantInfoPlusRes;
import com.sms.common.util.hutool.core.util.ObjectUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellRangeAddress;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 企业 BizService 层 接口
 *
 * @author Zj
 * @date 2021/12/7 20:13
 */
@Slf4j
@Service
public class TenantInfoPlusBizServiceImpl implements ITenantInfoPlusBizService {

    @Autowired
    TenantInfoPlusMapper tenantInfoPlusMapper;
    @Autowired
    private ConfInfoService confInfoService;


    /**
     * 企业证书信息统计导出表头
     */
    private final List<String> TENANT_COUNT_EXPORT_TITLE = Lists.newArrayList("序号", "企业名称", "信用代码", "联系电话", "最后一次登陆时间和用户", "本月登录次数", "上月登录次数");


    /**
     * 企业证书统计分页处理
     *
     * @param req 分页请求参数
     * @return 处理之后的视图
     */
    @Override
    public PageItemVO<TenantInfoPlusRes> pagingCount(PageItemDTO<TenantCountPagingReq> req) {
        Page<TenantInfoPlus> pageDo = new Page<>(req.getPageNum(), req.getPageSize());

        // 获取企业信息
        TenantInfoPlusDo tenantInfoPlusDo = new TenantInfoPlusDo();
        if (ObjectUtil.isNotNull(req.getConditions())) {
            BeanUtils.copyProperties(req.getConditions(), tenantInfoPlusDo);
        }
        Page<TenantInfoPlusPo> pagingPo = tenantInfoPlusMapper.pagingPo(pageDo, tenantInfoPlusDo);

        // 定义结果集
        PageItemVO<TenantInfoPlusRes> pagingRes = PageItemUtil.toPageItemVO(pagingPo, new PageItemVO<>());

        // 获取结果集
        pagingRes.setRecords(getTenantCertificateCountList(pagingPo.getRecords()));
        return pagingRes;

    }

    /**
     * 获取并导出所有企业证书统计信息
     *
     * @param conditionsReq 筛选条件
     * @return 结果集List
     */
    @Override
    public Workbook exportCount(TenantCountPagingReq conditionsReq) {
        TenantInfoPlusDo tenantInfoPlusDo = new TenantInfoPlusDo();
        BeanUtils.copyProperties(conditionsReq, tenantInfoPlusDo);
        List<TenantInfoPlusPo> tenantPoList = tenantInfoPlusMapper.queryList(tenantInfoPlusDo);

        // 获取证书类型字典表值
        Map<String, Object> params = new HashMap<>();
        params.put("type", CommonConstants.CONF_Certificate_Type);
        params.put("status", CommonConstants.CommonStatus.ENABLE);
        List<ConfInfo> certificateTypeList = confInfoService.query(params);

        return createPersonWorkbook(TENANT_COUNT_EXPORT_TITLE, getTenantCertificateCountList(tenantPoList), certificateTypeList);

    }

    /**
     * 创建企业证书信息统计导出列表
     *
     * @param title                    表格抬头
     * @param tenantCerInfoCountListPo 数据列表
     * @param certificateTypeList      证书类型列表
     * @return workbook
     */
    private Workbook createPersonWorkbook(List<String> title, List<TenantInfoPlusRes> tenantCerInfoCountListPo, List<ConfInfo> certificateTypeList) {
        HSSFWorkbook workbook = new HSSFWorkbook();

        HSSFCellStyle cellStyle = workbook.createCellStyle();
        cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
        // 创建表头
        HSSFSheet sheet = workbook.createSheet("企业证书信息统计表");

        int rowIndex = 1;
        Row row = sheet.createRow(rowIndex++);
        Cell cell;

        // 获取证书类型数量
        int certificateTypeCount = certificateTypeList.size();

        // 表头
        for (int i = 0; i < title.size() + certificateTypeCount; i++) {
            // 动态设置表头
            if (i == 4) {
                for (ConfInfo certificateType : certificateTypeList) {
                    cell = row.createCell(i);
                    cell.setCellValue(certificateType.getName() + "证书数量");
                    i++;
                }
            }
            cell = row.createCell(i);

            if (i > 4) {
                cell.setCellValue(title.get(i - certificateTypeCount));
            } else {
                cell.setCellValue(title.get(i));
            }
        }

        // 填写数据
        for (TenantInfoPlusRes res : tenantCerInfoCountListPo) {
            row = sheet.createRow(rowIndex);
            cell = row.createCell(0);
            cell.setCellValue(rowIndex - 1);
            cell = row.createCell(1);
            cell.setCellValue(res.getTenantName());
            cell = row.createCell(2);
            cell.setCellValue(res.getCertificateCode());
            cell = row.createCell(3);
            cell.setCellValue(res.getContactPersonMobile());
            // 动态添加证书类型数据
            int rowCount = 4;
            for (TenantInfoPlusRes.CertificateCount certificateCount : res.getCertificateCountList()) {
                System.out.println(certificateCount.getName());
                cell = row.createCell(rowCount);
                cell.setCellValue(certificateCount.getAmount());
                rowCount++;
            }
            // 设置登录人名+时间字段值
            cell = row.createCell(rowCount++);
            if (!StringUtils.isEmpty(res.getLastLoginUserName()) && !StringUtils.isEmpty(res.getLastLoginTime()))
                cell.setCellValue(res.getLastLoginUserName() + "(" + DateUtils.format(res.getLastLoginTime(), DateUtils.DATE_TIME_PATTERN) + ")");
            else
                cell.setCellValue("");

            cell = row.createCell(rowCount++);
            cell.setCellValue(res.getThisMonthLoginTimes());
            cell = row.createCell(rowCount);
            cell.setCellValue(res.getLastMonthLoginTimes());

            rowIndex++;
        }
        for (int i = 0; i < title.size(); i++) {
            sheet.autoSizeColumn(i);
        }
        // 标题
        row = sheet.createRow(0);
        row.setHeight((short) 300);
        cell = row.createCell(0);
        cell.setCellValue("证书信息统计");
        sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, title.size() + certificateTypeCount - 1));
        cell.setCellStyle(cellStyle);

        return workbook;
    }

    public List<TenantInfoPlusRes> getTenantCertificateCountList(List<TenantInfoPlusPo> tenantInfoPlusPos) {
        // 获取证书类型字典表值
        Map<String, Object> params = new HashMap<>();
        params.put("type", CommonConstants.CONF_Certificate_Type);
        params.put("status", CommonConstants.CommonStatus.ENABLE);
        List<ConfInfo> certificateTypeList = confInfoService.query(params);

        // 整合需要查询证书的企业id 统计企业证书数据
        List<Long> tenantIdList = tenantInfoPlusPos.stream().map(TenantInfoPlusPo::getTenantId).collect(Collectors.toList());
        params = new HashMap<>();
        params.put("tenantIdList", tenantIdList);
        List<TenantCertificateCount> tenantCertificateCountList = tenantInfoPlusMapper.listTenantCertificateCount(params);
        Map<Long, Map<String, Integer>> certificateCountMapByPIdTypeTenantId = tenantCertificateCountList.stream()
                .filter(po -> ObjectUtil.isNotNull(po.getTenantId()))
                .collect(Collectors.groupingBy(TenantCertificateCount::getTenantId,
                        Collectors.toMap(TenantCertificateCount::getpIdType, TenantCertificateCount::getAmount)));

        List<TenantInfoPlusRes> tenantCerInfoCountListPo = new ArrayList<>();
        TenantInfoPlusRes res;
        Map<String, Integer> certificateCountMapByPIdType;
        for (TenantInfoPlusPo listPo : tenantInfoPlusPos) {
            certificateCountMapByPIdType = new HashMap<>();
            res = new TenantInfoPlusRes();
            BeanUtils.copyProperties(listPo, res);
            if (certificateCountMapByPIdTypeTenantId.containsKey(listPo.getTenantId())) {
                certificateCountMapByPIdType = certificateCountMapByPIdTypeTenantId.get(listPo.getTenantId());
            }
            for (ConfInfo certificateType : certificateTypeList) {
                TenantInfoPlusRes.CertificateCount countRes = res.new CertificateCount();
                countRes.setName(certificateType.getValue());
                int amount;
                if (!certificateCountMapByPIdType.containsKey(certificateType.getCode())) {
                    amount = BigDecimal.ZERO.intValue();
                } else {
                    amount = certificateCountMapByPIdType.get(certificateType.getCode());
                }
                countRes.setAmount(amount);
                res.getCertificateCountList().add(countRes);
            }
            tenantCerInfoCountListPo.add(res);
        }

        return tenantCerInfoCountListPo;
    }

}
